const crypto = require("crypto");
const fs = require("fs");
const path = require("path");
const axios = require("axios");
const { pipeline } = require("stream");
const zlib = require('zlib');
const { promisify } = require('util');
const pipelineAsync = promisify(pipeline);

/**
 * 文件啊你工具
 */
class FileUtil {
    /**
     * 获取文件名称
     * @param {*} path 
     * @returns 
     */
    getFileNameByPath(path) {
        return path.replace(/\\/g, '/').split('/').pop();
    }

	/**
	 * 计算文件md5
	 * @param {*} path
	 * @returns
	 */
	getFileMD5(filePath) {
		return new Promise(resolve => {
			try {
				const hash = crypto.createHash("md5");
				const fileStream = fs.createReadStream(filePath);
				fileStream.on("data", data => {
					hash.update(data);
				});
				fileStream.on("end", () => {
					resolve(hash.digest("hex"));
				});
				fileStream.on("error", err => {
					console.log(err);
					resolve(null);
				});
			} catch (error) {
				console.log(error);
				resolve(null);
			}
		});
	}

	/**
	 * 获取文件大小
	 * @param {string} filePath
	 * @returns
	 */
	async getFileSize(filePath) {
        return new Promise(resolve => {
            try {
                fs.stat(filePath, (err, stats) => {
                    if (err) {
                        console.error('获取文件大小失败:', err);
                        return resolve(null);;
                    }
                    resolve(stats.size);
                });
            } catch (err) {
                console.error("获取文件大小失败:", err);
                return resolve(null);
            }
        })
	}

    /**
     * 创建文件夹
     * @param {*} dir
     */
    createFolder(dir){
        try {
            const fullPath = path.join(dir);
            fs.mkdirSync(fullPath, { recursive: true });
            console.log(`Directory created successfully at ${fullPath}`);
            return fullPath;
        } catch (error) {
            console.error(`Error creating directory: ${err.message}`);
            return null;
        }
    };

    /**
     * 下载文件
     * @param {*} url 图片路径
     * @param {*} savePath 保存路劲（需要带文件名称）
     * @returns 
     */
    downloadFile(url, savePath, isCreateFolder) {
        return new Promise(async resolve => {
            let writer = null;
            let response = null;
            try {
                console.log(`正在下载文件：${url} 至 ${savePath}`);
                // 是否需要创建文件夹
                if (isCreateFolder) {
                    await this.createFolder(savePath); // 创建目录
                }
                // 获取文件流
                response = await axios({
                    method: 'get',
                    url: url,
                    responseType: 'stream'
                });
                // 创建写入流
                writer = fs.createWriteStream(savePath);
                // 使用管道传输数据
                await pipelineAsync(response.data, writer);
                resolve(true);
                console.log(`文件下载成功: ${savePath}`);
            } catch (error) {
                writer.destroy();
                response.data.destroy();
                resolve(null);
                console.error('下载失败:', error.message);
            }
        })
    }

	/**
	 * 下载文件到指定路径
	 * @param {Array} images 文件列表
	 * @param {string} images[0].name 文件名
	 * @param {string} images[0].url 文件路径
	 * @param {Object} config 配置
	 * @param {string} config.downloadDir 文件下载路径
	 * @returns
	 */
	async downloadImages(images, config = {}) {
		const { downloadDir } = config;
		if (!downloadDir) {
			throw new Error(`The path for downloading the file must be passed`);
		}
		// 下载任务task
		const downloadItemTask = file => {
			return new Promise(async resolve => {
                let response;
                let writer;
				try {
                    // 创建读写流
					const imageUrl = file.url;
                    const savePath = path.join(downloadDir, file.name);
                    const downloadResult = await this.downloadFile(imageUrl, savePath);
                    if (!downloadResult) {
                        resolve({
                            originalUrl: file.url,
                            success: false,
                            error: '文件下载失败'
                        });
                        return;
                    }
                    // 获取文件大小
                    const fileSize = await this.getFileSize(savePath);
                    resolve({
                        originalUrl: imageUrl,
                        localPath: savePath,
                        size: fileSize,
                        success: true
                    });
				} catch (error) {
					console.error(`Error downloading image ${file.url}:`, error.message);
                    // 清理资源
                    if (writer) writer.destroy();
                    if (response && response.data) response.data.destroy();
					resolve({
						originalUrl: file.url,
						success: false,
						error: error.message
					});
				}
			});
		};
		const downloadResults = [];
        for (let i = 0, len = images.length; i < len; i++) {
            const { name, url } = images[i];
			if (typeof url === 'string' && url.match(/\.(jpg|jpeg|png|gif|webp)$/i)) {
                console.log(`***************** 图片(${i + 1}/${len})开始下载 *****************`)
				const downloadTask = await downloadItemTask({
					url: url,
					name: name
				});
				downloadResults.push(downloadTask);
                console.log(`***************** 图片(${i + 1}/${len})下载完毕 *****************`)
			}
        }
		return downloadResults;
	}
}

module.exports = new FileUtil();
